package com.spzx.product.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.spzx.product.api.vo.SkuLockVo;
import com.spzx.product.domain.SkuStock;
import com.spzx.product.mapper.SkuStockMapper;
import com.spzx.product.service.ISkuStockService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.spzx.product.vo.SkuStockVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Stream;

/**
 * <p>
 * 商品sku库存表 服务实现类
 * </p>
 *
 * @author Login
 * @since 2025-07-17
 */
@Service
public class SkuStockServiceImpl extends ServiceImpl<SkuStockMapper, SkuStock> implements ISkuStockService {

    @Autowired
    private RedisTemplate redisTemplate;
    @Override
    public SkuStockVo getSkuStock(Long skuId) {

        LambdaQueryWrapper<SkuStock> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SkuStock::getSkuId, skuId);
        SkuStock skuStock = baseMapper.selectOne(queryWrapper);

        SkuStockVo skuStockVo = new SkuStockVo();
        skuStockVo.setSkuId(skuId);
        skuStockVo.setSaleNum(skuStock.getSaleNum());
        skuStockVo.setAvailableNum(skuStock.getAvailableNum());
        return skuStockVo;
    }

    @Override
    public String checkAndLock(String orderNo,List<SkuLockVo> skuLockVoList  ) {
        //校验库存
        for (SkuLockVo skuLockVo : skuLockVoList) {
            SkuStock skuStock = baseMapper.check(skuLockVo.getSkuId(), skuLockVo.getSkuNum());
            if (skuStock == null){//库存不足
                skuLockVo.setHaveStock( false);
            }else {//库存充足
                skuLockVo.setHaveStock( true);
            }
        }
        if (skuLockVoList.stream().anyMatch(skuLockVo -> !skuLockVo.isHaveStock())){ //任何匹配的库存不足的商品都会被查询到
            List<SkuLockVo> skuLockVoListNotEnough = skuLockVoList.stream().filter(skuLockVo -> !skuLockVo.isHaveStock()).toList();//将库存不足的商品过滤出来放入列表 List<SkuLockVo>

            String errorMsg = ""; //错误信息
            for (SkuLockVo skuLockVo : skuLockVoListNotEnough){ //遍历库存不足的
                SkuStock skuStock = baseMapper.selectById(skuLockVo.getSkuId());
                Integer availableNum = skuStock.getAvailableNum(); //获取剩余库存

                errorMsg += skuLockVo.getSkuName() + "库存不足,剩余库存" + availableNum ;
            }
            return errorMsg;
        }else {
            for (SkuLockVo skuLock : skuLockVoList){
                //锁定库存
                baseMapper.lock(skuLock.getSkuId(), skuLock.getSkuNum());
            }
        }
        String dataKey = "order:lock:sku:" + orderNo;
        redisTemplate.opsForValue().set(dataKey,skuLockVoList);

        return "";
    }

    @Transactional(rollbackFor = {Exception.class})
    @Override
    public void unlock(String orderNo) {
        //幂等性处理
        //结合redis的处理方法
        String key = "sku:unlock"+orderNo; //自己随便写的
        Boolean isFirst = redisTemplate.opsForValue().setIfAbsent(key, orderNo,1, TimeUnit.MINUTES);
        //如果此方法被调用过，则直接返回
        if (!isFirst) return;

        //获取当前订单中的库存信息
        String dataKey = "order:lock:sku:" + orderNo;
        List<SkuLockVo> skuLockVoList = (List<SkuLockVo>)redisTemplate.opsForValue().get(dataKey);
        for (SkuLockVo skuLockVo : skuLockVoList){
            baseMapper.unlock(skuLockVo.getSkuId(),skuLockVo.getSkuNum());
        }
        //用完了后，删除redis中的数据
        redisTemplate.delete(dataKey);
    }
}
